import json
import re
import tempfile
import traceback
import os
import sys

from nonebot import on_command, get_driver
from nonebot.adapters import Bot, Event
from nonebot_plugin_alconna import Alconna, on_alconna, Args, Option, Arparma
from nonebot.adapters.onebot.v11 import MessageSegment

from newyear_drawchart import plot_3d_parkour


project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
sys.path.append(project_root)

from utils.num_to_chinese import num_to_chinese

usage_string = "qn用法： qn -s <计分板名(time|finaltime|level)> -o <输出模式(raw|pretty|simple|all)>"

# 定义Alconna命令
scoreboard_command = on_alconna(
    Alconna(
        "qwq_newyear",  # 主命令名
        Args(),
        Option("--output_mode|-o",      Args["output_mode_str", str]),
        Option("--scoreboard_name|-s",  Args["scoreboard_name_str",  str])
        # Option("--raw|-r"),  # 输出原始JSON
        # Option("--simple|-s"),  # 输出简化格式
        # Option("--pretty|-p"),  # 输出美化格式
        # Option("--chart|-c"),  # 输出图表格式
    ),
    aliases={".qn", "qn"}
)

# 处理命令的函数
@scoreboard_command.handle()
async def handle_scoreboard_command(bot: Bot, event: Event, result: Arparma):

    try:
        
        # await scoreboard_command.send(f"result.options = {result.options}")
        
        output_mode_str_value = "all"
        scoreboard_name_str_value = "finaltime"
        is_reversed = False
        
        if "output_mode" in result.options:
            output_mode_str_value = result.options["output_mode"].args.get('output_mode_str')
            
        if "scoreboard_name" in result.options:
            scoreboard_name_str_value = result.options["scoreboard_name"].args.get('scoreboard_name_str')
        
        if output_mode_str_value not in ["raw", "simple", "pretty", "all", "all_chart"]:
            await scoreboard_command.send(f"模式选项{output_mode_str_value}不存在！输出模式fallback至all")
            await scoreboard_command.send(usage_string)
            output_mode_str_value = "all"
        
        if scoreboard_name_str_value == "level":
            output_mode_str_value = "simple"
            is_reversed = True
            
        if ("scoreboard_name" in result.options) and ("output_mode" in result.options):
            if output_mode_str_value == "all":
                await scoreboard_command.send(f"选择了all模式以后就不需要指定计分板名字了")
        
        # 输出这些值
        # await scoreboard_command.send(f"output_mode_str_value = {output_mode_str_value}, scoreboard_str_value = {scoreboard_name_str_value}")
        if ( output_mode_str_value == "all" or output_mode_str_value == "all_chart" ):
            await scoreboard_command.send(f"【qwq_newyear】你选择的输出模式 = {output_mode_str_value}")
        else:
            await scoreboard_command.send(f"【qwq_newyear】你选择的输出模式 = {output_mode_str_value}, 你选择的计分板 = {scoreboard_name_str_value}")
        
        scoreboard_data = []
        if ( output_mode_str_value != "all" and output_mode_str_value != "all_chart"  ):
            scoreboard_data = read_and_parse_scoreboard_file(scoreboard_name_str_value) 
            if scoreboard_data == "FileNotFoundError": # 如果计分板文件不存在，返回错误信息
                await scoreboard_command.send(f"计分板文件 '{scoreboard_name_str_value}_logging.txt' 未找到！计分板选项fallback至finaltime")
                await scoreboard_command.send(usage_string)
                # scoreboard_name_str_value = "finaltime"
                scoreboard_data = read_and_parse_scoreboard_file()
            sorted_scoreboard_data = filter_and_sort_scoreboard(scoreboard_data, is_reversed)
        
            
        # await scoreboard_command.send(f"【qwq_scoreboard】你选择的输出模式 = {output_mode_str_value}，计分板名称 = {scoreboard_name_str_value}")
        
        if output_mode_str_value == "raw":
            await scoreboard_command.send(json.dumps(sorted_scoreboard_data, ensure_ascii=False, indent=4))
        elif output_mode_str_value == "simple":
            simple_output = [
                "---跑酷成绩计分板-新春限时活动-新春跑酷-LunarNewYearParkourCopy-simple---"
            ]
            for entry in sorted_scoreboard_data:
                simple_output.append(f"【{entry['playername']}】 {entry['data']}")
            await scoreboard_command.send("\n".join(simple_output))
        elif output_mode_str_value == "pretty":
            pretty_output = [
                "---跑酷成绩计分板-新春限时活动-新春跑酷-LunarNewYearParkourCopy-pretty---\n",
                "【本期速通视频】供参考: qwq网上暂时没有\n\n"
            ]
            for rank, entry in enumerate(sorted_scoreboard_data, start=1):
                # minutes = entry['data'] // 60
                # seconds = entry['data'] % 60
                # pretty_output.append(f"No.{rank} 【{entry['playername']}】 {minutes} m {seconds} s")
                
                t = entry['data'] / 20.0
                pretty_output.append( f"No.{num_to_chinese(rank+1)} 【{entry['playername']}】 {t:.2f} s\n" )
                
            await scoreboard_command.send("\n".join(pretty_output))
        elif output_mode_str_value == "all": 
            all_output = [
                "---跑酷成绩计分板-新春限时活动-新春跑酷-LunarNewYearParkourCopy-pretty---\n",
                "【本期速通视频】供参考: qwq网上暂时没有"
            ]
            # scoreboard_data_very_easy = read_and_parse_scoreboard_file("best_time_very_easy")
            # sorted_scoreboard_data_very_easy = filter_and_sort_scoreboard(scoreboard_data_very_easy, is_reversed)
            # scoreboard_data_easy = read_and_parse_scoreboard_file("best_time_easy")
            # sorted_scoreboard_data_easy = filter_and_sort_scoreboard(scoreboard_data_easy, is_reversed)
            # scoreboard_data_medium = read_and_parse_scoreboard_file("best_time_medium")
            # sorted_scoreboard_data_medium = filter_and_sort_scoreboard(scoreboard_data_medium, is_reversed)
            # scoreboard_data_hard = read_and_parse_scoreboard_file("best_time_hard")
            # sorted_scoreboard_data_hard = filter_and_sort_scoreboard(scoreboard_data_hard, is_reversed)
            
            def process_scoreboard(scoreboard_name_str_best_time, is_reversed):
                """处理单个排行榜文件，读取并排序"""
                scoreboard_data = read_and_parse_scoreboard_file(scoreboard_name_str_best_time)
                return filter_and_sort_scoreboard(scoreboard_data, is_reversed)

            # 文件名列表
            difficulty_levels = ["very_easy", "easy", "medium", "hard"]

            # 使用字典存储每个难度的排序数据
            sorted_scoreboards = {}

            # 遍历文件名并处理
            for difficulty in difficulty_levels:
                scoreboard_name_str_best_time = f"best_time_{difficulty}"
                sorted_scoreboards[difficulty] = process_scoreboard(scoreboard_name_str_best_time, is_reversed)
            
            # 遍历每个难度的前五名
            for difficulty, sorted_scoreboard_data in sorted_scoreboards.items():
                all_output += f"\n--- {difficulty} 难度排行榜 ---\n"
                cnt = 0  # 计数器，用于控制输出数量
                
                for entry in sorted_scoreboard_data:
                    # minutes = entry['data'] // 60
                    # seconds = entry['data'] % 60
                    # output_str += f"No.{num_to_chinese(cnt+1)} 【{entry['playername']}】 {minutes} m {seconds} s\n"
                    t = entry['data'] / 20.0
                    all_output += f"【{num_to_chinese(cnt+1)}】 {entry['playername']}: {t:.2f} s\n"
                    cnt += 1
                    if cnt >= 5:
                        break  # 达到 5 名后停止
                
            # 输出结果
            await scoreboard_command.send(all_output)
            # todo

        elif output_mode_str_value == "all_chart":
            difficulty_levels = ["very_easy", "easy", "medium", "hard"]
            all_scores = []
            for difficulty in difficulty_levels:
                # 读取并排序对应难度的排行榜数据
                scoreboard_data = read_and_parse_scoreboard_file(f"best_time_{difficulty}")
                sorted_data = filter_and_sort_scoreboard(scoreboard_data, is_reversed)
                # 提取分数列表
                # scores_list = [entry["data"] for entry in sorted_data]
                # all_scores.append(scores_list)
                chart_entries = [
                    {entry["playername"]: entry["data"]/20}  # 添加时间转换
                    for entry in sorted_data[:10]  # 最多取前10个
                ]
                all_scores.append(chart_entries)
            
            plot_3d_parkour(all_scores)
            
            # with open(chart_file_path, 'rb') as f:
            with open("parkour_scores.png", "rb") as img_file:
                image_bytes = img_file.read()
                message = MessageSegment.text(f"图表已生成：") + MessageSegment.image(image_bytes)
                await scoreboard_command.send(message)
            os.remove("parkour_scores.png")

        # elif output_mode_str == "--chart":
        #     with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as temp_img:
        #         temp_img_path = temp_img.name
                
        #         # 调用 drawchart_lib.create_ranking_chart 生成图片
        #         drawchart_lib.create_ranking_chart(sorted_scoreboard_data, temp_img_path)
                
        #         with open(temp_img_path, 'rb') as img_file:
        #             await bot.upload_file(img_file.read())
                    
        #         os.remove(temp_img_path)
                
                
    except Exception as e:
        stack_trace = traceback.format_exc()
        error_message = f"处理计分板时出错：\n{stack_trace}"
        await bot.send(event, error_message)
        
        
        

def read_and_parse_scoreboard_file(scoreboard_name="finaltime"):
    """读取并解析计分板文件"""
    # 根据指定的计分板名称生成文件路径
    # file_path = f"/mnt/data/SSoftwareFiles/minecraft/paper1.21.3-parkour/plugins/qwq-spigot-plugin/scoreboard_loggings/{scoreboard_name}/{scoreboard_name}_logging.txt"
    file_path = f"/mnt/vda1/SSoftwareFiles/minecraft/paper1.21.3-new_year_parkour/plugins/qwq-spigot-plugin/scoreboard_loggings/{scoreboard_name}/{scoreboard_name}_logging.txt"
    scoreboard_entries = []

    uuid_pattern = re.compile(r'^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$', re.IGNORECASE)

    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            for line in f:
                parts = line.strip().split(": ")
                if len(parts) == 2:
                    key, value = parts
                    if not uuid_pattern.match(key):  # 排除UUID格式的条目
                        scoreboard_entries.append({"playername": key, "data": int(value)})
    except FileNotFoundError:
        return "FileNotFoundError"  # 如果文件找不到，则返回 None

    return scoreboard_entries

# 封装过滤和排序逻辑的函数
def filter_and_sort_scoreboard(scoreboard_data, is_reversed=False):
    excluded_players = {
        "rank_s", "rank_a", "rank_b", "rank_c", "CONSOLE", "minute", "hour",
        "Hielke", "Hielkez", "DeKracht"
    }
    filtered_scoreboard_data = [entry for entry in scoreboard_data if entry['playername'] not in excluded_players and entry['data'] != 0]
    sorted_scoreboard_data = sorted(filtered_scoreboard_data, key=lambda x: x['data'], reverse=is_reversed)
    return sorted_scoreboard_data
